package com.sugon.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.AuthCheck;
import com.sugon.annotation.LoginUser;
import com.sugon.dao.DevMaintenanceTicketItemDao;
import com.sugon.entity.*;
import com.sugon.modules.todo.consts.TodoSource;
import com.sugon.modules.alarm.service.AlarmCodeBaseService;
import com.sugon.modules.device.model.vo.DevMaintenanceTicketItemDetailVO;
import com.sugon.modules.device.model.vo.ExceptionUploadParam;
import com.sugon.modules.sys.model.vo.PickerModel;
import com.sugon.modules.sys.utils.FaultTypeTreeNodeUtils;
import com.sugon.modules.todo.consts.TodoStatus;
import com.sugon.service.*;
import com.sugon.util.ApiBaseAction;
import com.sugon.util.ApiPageUtils;
import com.sugon.utils.Query;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "设备基础查询API,包含根据设备编码查询设备基础信息、维护履历和维修履历")
@RestController
@RequestMapping("/api/v1/devices")
public class DeviceBaseApiController extends ApiBaseAction {

    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private DevMaintenanceTicketItemDao devMaintenanceTicketItemDao;
    @Autowired
    private SparePartDevService sparePartDevService;
    @Autowired
    private DevTypeService devTypeService;
    @Resource
    private AlarmCodeBaseService alarmCodeBaseService;
    @Resource
    private AlarmCategoryService alarmCategoryService;
    @Resource
    private DevRepairRecordService devRepairRecordService;
    @Resource
    private DevMaintenanceTicketService pmTicketService;
    @Resource
    private DevAmTicketService amTicketService;
    @Resource
    private InspectionRecordingJoinService inspectService;
    @Resource
    private ErmsTodoListService todoListService;
    @Resource
    private SysDeptService deptService;

    @AuthCheck
    @ApiOperation(value = "获取设备报警分类API")
    @RequestMapping("/getDevAlarmType")
    public ApiResult<Object> getDevAlarmType(@RequestParam String devId) {
        ApiResult<Object> result = new ApiResult<>();
        // 校验设备是否存在
        DeviceInfoEntity device = deviceInfoService.queryObject(devId);
        if (device == null) {
            return result.failMsg("设备不存在，请确认！");
        }
        // 获取VRT
        AlarmCategoryEntity vrt = alarmCategoryService.queryByCategoryCode(device.getDevTypeS());
        if (vrt == null) {
            return result.failMsg("该设备分类所属的报警分类尚未完善，！");
        }
        // 获取VRT下所有的报警分类列表
        List<PickerModel> modelList = new ArrayList<>();
        List<AlarmCategoryEntity> alarmCategoryList = alarmCategoryService.listByCode(vrt.getCode());

        // 整合数据到一起
        for (AlarmCategoryEntity alarmCategory : alarmCategoryList) {
            modelList.add(new PickerModel(alarmCategory.getName(), alarmCategory.getId(), alarmCategory.getPid()));
        }
        // 构建设备组织树
        FaultTypeTreeNodeUtils treeNodeUtils = new FaultTypeTreeNodeUtils(modelList);
        PickerModel root = treeNodeUtils.generateTree(vrt.getId());
        return result.success(root.getChildren());
    }

    @AuthCheck
    @ApiOperation(value = "查询指定设备的报警代码库API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "devId", value = "设备ID", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "alarmCode", value = "故障代码", paramType = "query", dataType = "string"),
            @ApiImplicitParam(name = "alarmCategoryId", value = "报警分类ID", paramType = "query", dataType = "string")
    })
    @PostMapping("/alarmCodeBase")
    public ApiResult<List<AlarmCodeBaseEntity>> queryAll(@RequestParam String devId, String alarmCode, String alarmCategoryId) {
        ApiResult<List<AlarmCodeBaseEntity>> apiResult = new ApiResult<>();
        return apiResult.success(alarmCodeBaseService.queryList(alarmCategoryId, devId, alarmCode));
    }

    @AuthCheck
    @ApiOperation(value = "查询设备分类API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "typeTp", value = "类型标志 0 小类 1中类 2大类", paramType = "query", dataType = "int", defaultValue = "2", required = true, allowableValues = "0,1,2"),
            @ApiImplicitParam(name = "typePid", value = "上级类型编码", paramType = "query", dataType = "String")
    })
    @PostMapping("/type")
    public ApiResult<List<DevTypeEntity>> queryAll(@ApiIgnore @RequestParam(required = false) Map<String, Object> params) {
        ApiResult<List<DevTypeEntity>> apiResult = new ApiResult<>();
        params.put("sidx", "TYPE_CODE");
        params.put("order", "asc");
        return apiResult.success(devTypeService.queryList(params));
    }

    @AuthCheck
    @ApiOperation(value = "查询车间列表API")
    @PostMapping("/listCj")
    public ApiResult<List<SysDeptEntity>> listCj() {
        ApiResult<List<SysDeptEntity>> apiResult = new ApiResult<>();
        return apiResult.success(deptService.listDeviceOrganization(2));
    }

    @AuthCheck
    @ApiOperation(value = "异常上报API", notes = "目前主要适用于设备维修或者维护中的异常上报！")
    @PostMapping("/uploadException")
    public ApiResult<String> uploadException(@ApiIgnore @LoginUser SysUserEntity loginUser, @RequestBody @Validated ExceptionUploadParam exceptionUploadParam, BindingResult bindingResult) {
        // 常规校验
        ApiResult<String> apiResult = getValidApiResult(bindingResult);
        if (apiResult != null) {
            return apiResult;
        }
        apiResult = new ApiResult<>();
        String devId;
        // 判定是否是支持的异常上报类型
        TodoSource todoSource = TodoSource.getInstanceByValue(exceptionUploadParam.getSource());
        if (todoSource == null) {
            return apiResult.failMsg("暂不支持该来源的异常上报！");
        }
        if (TodoSource.REPAIR == todoSource) {
            DevRepairRecordEntity repairRecord = devRepairRecordService.queryObject(exceptionUploadParam.getOriginRecordId());
            if (repairRecord == null) {
                return apiResult.failMsg("维修工单不存在，请确认！");
            }
            devId = repairRecord.getDevId();
        } else if (TodoSource.PM == todoSource) {
            DevMaintenanceTicketEntity pmTicket = pmTicketService.queryObject(exceptionUploadParam.getOriginRecordId());
            if (pmTicket == null) {
                return apiResult.failMsg("预防维护工单不存在，请确认！");
            }
            devId = pmTicket.getDevId();
        } else if (TodoSource.AM == todoSource) {
            DevAmTicketEntity amTicket = amTicketService.queryObject(exceptionUploadParam.getOriginRecordId());
            if (amTicket == null) {
                return apiResult.failMsg("自主维护工单不存在，请确认！");
            }
            devId = amTicket.getDevId();
        } else if (TodoSource.INSPECT == todoSource) {
            InspectionRecordingJoinEntity inspectRecord = inspectService.queryObject(exceptionUploadParam.getOriginRecordId());
            if (inspectRecord == null) {
                return apiResult.failMsg("设备巡检记录不存在，请确认！");
            }
            devId = inspectRecord.getDevId();
        } else if (TodoSource.FAULT_ANALYSE == todoSource) {
            DevRepairRecordEntity repairRecord = devRepairRecordService.queryObject(exceptionUploadParam.getOriginRecordId());
            if (repairRecord == null) {
                return apiResult.failMsg("维修工单不存在，请确认！");
            }
            devId = repairRecord.getDevId();
        } else {
            return apiResult.failMsg("暂不支持该来源的异常上报！");
        }
        DeviceInfoEntity device = deviceInfoService.queryObject(devId);
        Assert.notNull(device);
        // 保存异常记录信息
        ErmsTodoList todoItem = new ErmsTodoList();
        CopyOptions copyOptions = CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true);
        BeanUtil.copyProperties(exceptionUploadParam, todoItem, copyOptions);
        todoItem.setDevId(devId);
        todoItem.setExType(todoSource.getExType());
        todoItem.setWorkshopId(StrUtil.sub(device.getDeptCode(), 0, 4));
        todoItem.setCreateBy(loginUser.getUserId());
        todoItem.setStatus(TodoStatus.UN);
        return todoListService.save(todoItem) > 0 ? apiResult.success() : apiResult.fail();
    }

    /**
     * 获取设备关联备件列表API
     *
     * @param loginUser
     * @param params
     * @return
     */
    @AuthCheck
    @ApiOperation(value = "获取设备关联备件列表API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "devId", value = "设备编码", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "keyword", value = "备件关键字", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", required = true),
            @ApiImplicitParam(name = "limit", value = "每页记录数", paramType = "query", dataType = "int", required = true)
    })
    @PostMapping("/loadRelatedSparePartList")
    public ApiResult<ApiPageUtils> getRelatedSparePartList(@ApiIgnore @LoginUser SysUserEntity loginUser, @RequestParam Map<String, Object> params) {
        ApiResult<ApiPageUtils> apiResult = new ApiResult<>();
        //查询列表数据
        Query query = new Query(params);
        List<SparePartDevEntity> sparePartDevList = sparePartDevService.devQueryList(query);
        int total = sparePartDevService.devQueryTotal(query);
        ApiPageUtils pageUtil = new ApiPageUtils(sparePartDevList, total, query.getLimit(), query.getPage());
        return apiResult.success(pageUtil);
    }


    @AuthCheck
    @ApiOperation(value = "根据设备编码查询设备列表API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "devCode", value = "设备编码或ERP编码", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isModuleRelated", value = "是否关联模具", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "limit", value = "每页记录数", paramType = "query", dataType = "Integer", required = true)
    })
    @PostMapping
    public ApiResult<ApiPageUtils> getDevList(@ApiIgnore @LoginUser SysUserEntity loginUser, @RequestParam Map<String, Object> params) {
        ApiResult<ApiPageUtils> apiResult = new ApiResult<>();
        //查询列表数据
        Query map = new Query(params);
        List<DeviceInfoEntity> deviceInfoList = deviceInfoService.queryList(params);
        int total = deviceInfoService.queryTotal(params);
        ApiPageUtils pageUtil = new ApiPageUtils(deviceInfoList, total, map.getLimit(), map.getPage());
        return apiResult.success(pageUtil);
    }

    @AuthCheck
    @ApiOperation(value = "分页获取设备维修履历API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "devId", value = "设备ID", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "limit", value = "每页记录数", paramType = "query", dataType = "Integer", required = true)
    })
    @PostMapping("/repairRecords")
    public ApiResult<ApiPageUtils> getDevRepairRecords(@RequestParam Map<String, Object> params) {
        ApiResult<ApiPageUtils> apiResult = new ApiResult<>();
        // 添加默认分页条件
        params.put("sidx", "CREATE_DATE");
        params.put("order", "DESC");
        params.put("isImplemented", 1);
        //查询列表数据
        Query map = new Query(params);
        List<DevMaintenanceTicketItemDetailVO> deviceInfoList = devMaintenanceTicketItemDao.queryAll(map);
        int total = devMaintenanceTicketItemDao.queryTotal(map);
        ApiPageUtils pageUtil = new ApiPageUtils(deviceInfoList, total, map.getLimit(), map.getPage());
        return apiResult.success(pageUtil);
    }

    @AuthCheck
    @ApiOperation(value = "分页获取设备维护履历API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "limit", value = "每页记录数", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "devId", value = "设备ID", paramType = "query", dataType = "String", required = true)
    })
    @PostMapping("/maintenanceRecords")
    public ApiResult<ApiPageUtils> getDevMaintenanceRecords(
            @ApiIgnore @LoginUser SysUserEntity loginUser,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "size", defaultValue = "20") Integer size,
            @RequestParam(value = "devId") String devId) {
        ApiResult<ApiPageUtils> apiResult = new ApiResult<>();
        Map<String, Object> params = new HashMap<>(6);
        params.put("page", page);
        params.put("limit", size);
        params.put("sidx", "CREATE_DATE");
        params.put("order", "DESC");
        params.put("devId", devId);
        params.put("isImplemented", 1);
        //查询列表数据
        Query map = new Query(params);
        List<DevMaintenanceTicketItemDetailVO> deviceInfoList = devMaintenanceTicketItemDao.queryAll(map);
        int total = devMaintenanceTicketItemDao.queryTotal(map);
        ApiPageUtils pageUtil = new ApiPageUtils(deviceInfoList, total, map.getLimit(), map.getPage());
        return apiResult.success(pageUtil);
    }

}
